package com.hwxm.ltim.service;

import com.alibaba.fastjson2.JSON;
import com.hwxm.ltim.constant.MessageType;
import com.hwxm.ltim.entity.message.MessageRequest;
import com.hwxm.ltim.entity.message.MessageResponse;
import com.hwxm.ltim.util.ChannelManager;
import com.hwxm.ltim.util.JwtUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 消息处理服务
 */
@Slf4j
@Service
public class MessageService {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private ChatMessageService chatMessageService;

    /**
     * 处理消息
     */
    public void handleMessage(ChannelHandlerContext ctx, MessageRequest request) {
        Integer type = request.getType();

        switch (type) {
            case MessageType.LOGIN:
                handleLogin(ctx, request);
                break;
            case MessageType.PRIVATE_CHAT:
                handlePrivateChat(ctx, request);
                break;
            case MessageType.GROUP_CHAT:
                handleGroupChat(ctx, request);
                break;
            case MessageType.HEARTBEAT:
                handleHeartbeat(ctx, request);
                break;
            case MessageType.READ_ACK:
                handleReadAck(ctx, request);
                break;
            default:
                log.warn("未知的消息类型：{}", type);
        }
    }

    /**
     * 处理登录认证
     */
    private void handleLogin(ChannelHandlerContext ctx, MessageRequest request) {
        String token = request.getToken();
        
        try {
            // 验证 token
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                sendResponse(ctx, MessageResponse.error(MessageType.LOGIN, "token 无效"));
                return;
            }

            // 绑定用户与通道
            ChannelManager.bindUserChannel(userId, ctx.channel());

            // 发送登录成功响应
            MessageResponse response = MessageResponse.success(MessageType.LOGIN, "登录成功", userId);
            sendResponse(ctx, response);

            log.info("用户 {} 登录成功", userId);

            // 推送离线消息
            chatMessageService.pushOfflineMessages(userId);

        } catch (Exception e) {
            log.error("登录处理失败", e);
            sendResponse(ctx, MessageResponse.error(MessageType.LOGIN, "登录失败"));
        }
    }

    /**
     * 处理单聊消息
     */
    private void handlePrivateChat(ChannelHandlerContext ctx, MessageRequest request) {
        try {
            Long senderId = request.getSenderId();
            Long receiverId = request.getReceiverId();

            // 保存消息到数据库
            chatMessageService.savePrivateMessage(request);

            // 如果接收者在线，直接推送
            if (ChannelManager.isOnline(receiverId)) {
                MessageResponse response = MessageResponse.success(MessageType.PRIVATE_CHAT, "新消息", request);
                String message = JSON.toJSONString(response);
                ChannelManager.sendToUser(receiverId, message);
                log.info("消息已推送：{} -> {}", senderId, receiverId);
            } else {
                log.info("用户 {} 离线，消息已保存", receiverId);
            }

            // 向发送者确认消息已发送
            MessageResponse ackResponse = MessageResponse.success(MessageType.PRIVATE_CHAT, "消息已发送", request.getMsgId());
            sendResponse(ctx, ackResponse);

        } catch (Exception e) {
            log.error("单聊消息处理失败", e);
            sendResponse(ctx, MessageResponse.error(MessageType.PRIVATE_CHAT, "消息发送失败"));
        }
    }

    /**
     * 处理群聊消息
     */
    private void handleGroupChat(ChannelHandlerContext ctx, MessageRequest request) {
        try {
            Long senderId = request.getSenderId();
            Long groupId = request.getGroupId();

            // 保存消息到数据库
            chatMessageService.saveGroupMessage(request);

            // 获取群成员并推送消息
            chatMessageService.pushGroupMessage(groupId, request);

            // 向发送者确认消息已发送
            MessageResponse ackResponse = MessageResponse.success(MessageType.GROUP_CHAT, "消息已发送", request.getMsgId());
            sendResponse(ctx, ackResponse);

            log.info("群消息已发送：群组 {} 用户 {}", groupId, senderId);

        } catch (Exception e) {
            log.error("群聊消息处理失败", e);
            sendResponse(ctx, MessageResponse.error(MessageType.GROUP_CHAT, "消息发送失败"));
        }
    }

    /**
     * 处理心跳
     */
    private void handleHeartbeat(ChannelHandlerContext ctx, MessageRequest request) {
        MessageResponse response = MessageResponse.success(MessageType.HEARTBEAT, "pong", null);
        sendResponse(ctx, response);
    }

    /**
     * 处理已读回执
     */
    private void handleReadAck(ChannelHandlerContext ctx, MessageRequest request) {
        try {
            // 更新消息已读状态
            chatMessageService.markMessageAsRead(request.getMsgId(), request.getSenderId());
            log.info("消息已读：{}", request.getMsgId());
        } catch (Exception e) {
            log.error("已读回执处理失败", e);
        }
    }

    /**
     * 发送响应
     */
    private void sendResponse(ChannelHandlerContext ctx, MessageResponse response) {
        String message = JSON.toJSONString(response);
        ctx.channel().writeAndFlush(new TextWebSocketFrame(message));
    }
}

